1   /*
2    * Copyright (C) 2007 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.collect.testing.testers;
18  
19  import static com.google.common.collect.testing.features.CollectionSize.ONE;
20  import static com.google.common.collect.testing.features.CollectionSize.ZERO;
21  import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
22  import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
23  import static com.google.common.collect.testing.features.MapFeature.REJECTS_DUPLICATES_AT_CREATION;
24  
25  import com.google.common.annotations.GwtCompatible;
26  import com.google.common.annotations.GwtIncompatible;
27  import com.google.common.collect.testing.AbstractMapTester;
28  import com.google.common.collect.testing.Helpers;
29  import com.google.common.collect.testing.features.CollectionSize;
30  import com.google.common.collect.testing.features.MapFeature;
31  
32  import java.lang.reflect.Method;
33  import java.util.Arrays;
34  import java.util.List;
35  import java.util.Map.Entry;
36  
37  /**
38   * A generic JUnit test which tests creation (typically through a constructor or
39   * static factory method) of a map. Can't be invoked directly; please see
40   * {@link com.google.common.collect.testing.MapTestSuiteBuilder}.
41   *
42   * @author Chris Povirk
43   * @author Kevin Bourrillion
44   */
45  @GwtCompatible(emulated = true)
46  public class MapCreationTester<K, V> extends AbstractMapTester<K, V> {
47    @MapFeature.Require(ALLOWS_NULL_KEYS)
48    @CollectionSize.Require(absent = ZERO)
49    public void testCreateWithNullKeySupported() {
50      initMapWithNullKey();
51      expectContents(createArrayWithNullKey());
52    }
53  
54    @MapFeature.Require(absent = ALLOWS_NULL_KEYS)
55    @CollectionSize.Require(absent = ZERO)
56    public void testCreateWithNullKeyUnsupported() {
57      try {
58        initMapWithNullKey();
59        fail("Creating a map containing a null key should fail");
60      } catch (NullPointerException expected) {
61      }
62    }
63  
64    @MapFeature.Require(ALLOWS_NULL_VALUES)
65    @CollectionSize.Require(absent = ZERO)
66    public void testCreateWithNullValueSupported() {
67      initMapWithNullValue();
68      expectContents(createArrayWithNullValue());
69    }
70  
71    @MapFeature.Require(absent = ALLOWS_NULL_VALUES)
72    @CollectionSize.Require(absent = ZERO)
73    public void testCreateWithNullValueUnsupported() {
74      try {
75        initMapWithNullValue();
76        fail("Creating a map containing a null value should fail");
77      } catch (NullPointerException expected) {
78      }
79    }
80  
81    @MapFeature.Require({ALLOWS_NULL_KEYS, ALLOWS_NULL_VALUES})
82    @CollectionSize.Require(absent = ZERO)
83    public void testCreateWithNullKeyAndValueSupported() {
84      Entry<K, V>[] entries = createSamplesArray();
85      entries[getNullLocation()] = entry(null, null);
86      resetMap(entries);
87      expectContents(entries);
88    }
89  
90    @MapFeature.Require(value = ALLOWS_NULL_KEYS,
91        absent = REJECTS_DUPLICATES_AT_CREATION)
92    @CollectionSize.Require(absent = {ZERO, ONE})
93    public void testCreateWithDuplicates_nullDuplicatesNotRejected() {
94      expectFirstRemoved(getEntriesMultipleNullKeys());
95    }
96  
97    @MapFeature.Require(absent = REJECTS_DUPLICATES_AT_CREATION)
98    @CollectionSize.Require(absent = {ZERO, ONE})
99    public void testCreateWithDuplicates_nonNullDuplicatesNotRejected() {
100     expectFirstRemoved(getEntriesMultipleNonNullKeys());
101   }
102 
103   @MapFeature.Require({ALLOWS_NULL_KEYS, REJECTS_DUPLICATES_AT_CREATION})
104   @CollectionSize.Require(absent = {ZERO, ONE})
105   public void testCreateWithDuplicates_nullDuplicatesRejected() {
106     Entry<K, V>[] entries = getEntriesMultipleNullKeys();
107     try {
108       resetMap(entries);
109       fail("Should reject duplicate null elements at creation");
110     } catch (IllegalArgumentException expected) {
111     }
112   }
113 
114   @MapFeature.Require(REJECTS_DUPLICATES_AT_CREATION)
115   @CollectionSize.Require(absent = {ZERO, ONE})
116   public void testCreateWithDuplicates_nonNullDuplicatesRejected() {
117     Entry<K, V>[] entries = getEntriesMultipleNonNullKeys();
118     try {
119       resetMap(entries);
120       fail("Should reject duplicate non-null elements at creation");
121     } catch (IllegalArgumentException expected) {
122     }
123   }
124 
125   private Entry<K, V>[] getEntriesMultipleNullKeys() {
126     Entry<K, V>[] entries = createArrayWithNullKey();
127     entries[0] = entry(null, entries[0].getValue());
128     return entries;
129   }
130 
131   private Entry<K, V>[] getEntriesMultipleNonNullKeys() {
132     Entry<K, V>[] entries = createSamplesArray();
133     entries[0] = entry(samples.e1.getKey(), samples.e0.getValue());
134     return entries;
135   }
136 
137   private void expectFirstRemoved(Entry<K, V>[] entries) {
138     resetMap(entries);
139 
140     List<Entry<K, V>> expectedWithDuplicateRemoved =
141         Arrays.asList(entries).subList(1, getNumElements());
142     expectContents(expectedWithDuplicateRemoved);
143   }
144 
145   /**
146    * Returns the {@link Method} instance for {@link
147    * #testCreateWithNullKeyUnsupported()} so that tests can suppress it
148    * with {@code FeatureSpecificTestSuiteBuilder.suppressing()} until <a
149    * href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5045147">Sun
150    * bug 5045147</a> is fixed.
151    */
152   @GwtIncompatible("reflection")
153   public static Method getCreateWithNullKeyUnsupportedMethod() {
154     return Helpers.getMethod(MapCreationTester.class, "testCreateWithNullKeyUnsupported");
155   }
156 }